package com.ruicar.afs.cloud.afscase.channel.service.impl;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.channel.common.Constants;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelBaseInfo;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelQuotaInfo;
import com.ruicar.afs.cloud.afscase.channel.feign.ChannelFeignService;
import com.ruicar.afs.cloud.afscase.channel.mapper.ChannelQuotaInfoMapper;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelBaseInfoService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelQuotaInfoService;
import com.ruicar.afs.cloud.afscase.channel.utils.CaseConfig;
import com.ruicar.afs.cloud.afscase.channel.vo.ChannelLimitTakeUpOrLeaseVo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.LoanModelEnum;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.QuotaTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruicar.afs.cloud.afscase.channel.utils.Common.QUOTA_TYPE_MORTGAGE;
import static com.ruicar.afs.cloud.afscase.channel.utils.Common.QUOTA_TYPE_TAKE_UP;

/**
 * @author mingzhi.li
 * @version 1.0
 * @describe 渠道保证金维护
 * @date 2020/06/9 11：20
 */
@Service
public class ChannelQuotaInfoServiceImpl extends ServiceImpl<ChannelQuotaInfoMapper, ChannelQuotaInfo> implements ChannelQuotaInfoService {

    @Autowired
    private ChannelFeignService channelFeignService;
    @Autowired
    private CaseConfig caseConfig;

    @Autowired
    private ChannelBaseInfoService channelBaseInfoService;
    @Autowired
    private CaseChannelInfoService caseChannelInfoService;
    @Autowired
    private CaseContractInfoService caseContractInfoService;
    @Autowired
    private ApplyCostDetailsService applyCostDetailsService;


    @Override
    public void updateQuotaLimit(ChannelLimitTakeUpOrLeaseVo vo, List<ChannelQuotaInfo> quotaInfoList) {

        ChannelQuotaInfo info = quotaInfoList.get(0);
        //判断条件：占用
        if (QUOTA_TYPE_TAKE_UP.equals(vo.getOperType())) {
            //获取现有占用额度
            BigDecimal occupiedQuota = info.getOccupiedQuota() == null ? BigDecimal.ZERO : info.getOccupiedQuota();
            //最新占用额度（占用额度增加）=原始数据库占用额度+此次占用额度
            info.setOccupiedQuota(occupiedQuota.add(vo.getQuotaAmount()));

            //获取现有剩余额度
            BigDecimal surplusQuota = info.getSurplusQuota() == null ? BigDecimal.ZERO : info.getSurplusQuota();
            //最新剩余额度（占用额度减少）=原始数据库剩余额度-此次占用金额
            info.setSurplusQuota(surplusQuota.subtract(vo.getQuotaAmount()));
            this.updateById(info);
        }
        //判断条件：释放
        else if (QUOTA_TYPE_MORTGAGE.equals(vo.getOperType())) {
            //获取现有占用额度
            BigDecimal occupiedQuota = info.getOccupiedQuota() == null ? BigDecimal.ZERO : info.getOccupiedQuota();
            //最新占用额度（占用额度减少）=原始数据库占用额度-此次释放额度
            info.setOccupiedQuota(occupiedQuota.subtract(vo.getQuotaAmount()));

            //获取现有剩余额度
            BigDecimal surplusQuota = info.getSurplusQuota() == null ? BigDecimal.ZERO : info.getSurplusQuota();
            //最新剩余额度（占用额度增加）=原始数据库剩余额度+此次释放金额
            info.setSurplusQuota(surplusQuota.add(vo.getQuotaAmount()));
            this.updateById(info);
        }
    }


    /**
     * 同步临时额度数据到渠道服务
     *
     * @param quotaInfoList
     */
    @Override
    public IResponse synchronousLimitToChannel(List<ChannelQuotaInfo> quotaInfoList) {
        //请求头
        Map<String, String> headers = new HashMap<>();
        //接口返回结果
        headers.put("clientId", caseConfig.getChannelClientId());
        headers.put("clientSecret", caseConfig.getChannelClientSecret());
        IResponse result = (IResponse) channelFeignService.synchronousLimitToChannel(quotaInfoList, headers);
        //结果解析只有成功时，方可返回正确的值
        return IResponse.success(result);
    }


    /*
     * 额度重算
     * */
    @Override
    public void quotaRecompute(List<Long> channelIds, String businessType) {

        List<ChannelQuotaInfo> totalChannelQuotaInfoList = new ArrayList<>();
        if (channelIds.size() > 0) {
            for (Long channelId : channelIds) {
                //首先根据渠道id获取该合作的所有合同信息
                ChannelBaseInfo baseInfo = channelBaseInfoService.getById(channelId);
                String channelCode = baseInfo.getChannelCode();

                //获取该合作商所有案件列表
                List<CaseChannelInfo> caseChannelInfoList = caseChannelInfoService.list(Wrappers.<CaseChannelInfo>query().lambda()
                        .eq(CaseChannelInfo::getDealerNo, channelCode)
                );
                List<FinCostDetails> beforeFinCostDetailsList = new ArrayList<>();
                List<FinCostDetails> signFinCostDetailsList = new ArrayList<>();
                if (caseChannelInfoList.size() > 0) {
                    for (CaseChannelInfo caseChannelInfo : caseChannelInfoList) {
                        //先放后抵押额度
                        CaseContractInfo before = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                                .eq(CaseContractInfo::getApplyNo, caseChannelInfo.getApplyNo())
                                .eq(CaseContractInfo::getBusinessType, businessType)
                                .eq(CaseContractInfo::getQuotaStatus, Constants.QUOTA_OCCUPATION)
                                .eq(CaseContractInfo::getLendingMode, AfsEnumUtil.key(LoanModelEnum.beforeMortgage)));
                        //签约放款额度
                        CaseContractInfo sign = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                                .eq(CaseContractInfo::getApplyNo, caseChannelInfo.getApplyNo())
                                .eq(CaseContractInfo::getBusinessType, businessType)
                                .eq(CaseContractInfo::getQuotaStatus, Constants.QUOTA_OCCUPATION)
                                .eq(CaseContractInfo::getLendingMode, AfsEnumUtil.key(LoanModelEnum.sign)));

                        if (before != null) {
                            List<FinCostDetails> beforeFinCostDetails = applyCostDetailsService.list(Wrappers.<FinCostDetails>query().lambda()
                                    .eq(FinCostDetails::getApplyNo, before.getApplyNo()));
                            if (beforeFinCostDetails.size() > 0) beforeFinCostDetailsList.addAll(beforeFinCostDetails);
                        }
                        if (sign != null) {
                            List<FinCostDetails> signFinCostDetails = applyCostDetailsService.list(Wrappers.<FinCostDetails>query().lambda()
                                    .eq(FinCostDetails::getApplyNo, sign.getApplyNo()));
                            if (signFinCostDetails.size() > 0) signFinCostDetailsList.addAll(signFinCostDetails);
                        }
                    }
                    //同步渠道用
                    List<ChannelQuotaInfo> channelQuotaInfoList = new ArrayList<>();
                    if (beforeFinCostDetailsList.size() > 0) {
                        //累加先抵后放占用额度
                        BigDecimal beforeOccupiedQuota = beforeFinCostDetailsList.stream().map(cost -> cost.getLoanAmt() == null ? BigDecimal.ZERO : cost.getLoanAmt())
                                .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                        ChannelQuotaInfo beforeQuota = this.getOne(Wrappers.<ChannelQuotaInfo>query().lambda()
                                .eq(ChannelQuotaInfo::getBusinessType, businessType)
                                .eq(ChannelQuotaInfo::getChannelId, channelId)
                                .eq(ChannelQuotaInfo::getQuotaType, QuotaTypeEnum.beforeMortgage.getCode())
                        );
                        BigDecimal quota = beforeQuota.getQuotaAmount() == null ? BigDecimal.ZERO : beforeQuota.getQuotaAmount();
                        BigDecimal tempQuota = beforeQuota.getTempQuota() == null ? BigDecimal.ZERO : beforeQuota.getTempQuota();
                        beforeQuota.setOccupiedQuota(beforeOccupiedQuota);
                        //剩余额度 = 签放额度+临时额度-占用额度
                        beforeQuota.setSurplusQuota(quota.add(tempQuota).subtract(beforeOccupiedQuota));
                        updateById(beforeQuota);
                        totalChannelQuotaInfoList.add(beforeQuota);
                    }

                    if (signFinCostDetailsList.size() > 0) {
                        //累加签放占用额度
                        BigDecimal signOccupiedQuota = signFinCostDetailsList.stream().map(cost -> cost.getLoanAmt() == null ? BigDecimal.ZERO : cost.getLoanAmt())
                                .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                        ChannelQuotaInfo signQuota = this.getOne(Wrappers.<ChannelQuotaInfo>query().lambda()
                                .eq(ChannelQuotaInfo::getBusinessType, businessType)
                                .eq(ChannelQuotaInfo::getChannelId, channelId)
                                .eq(ChannelQuotaInfo::getQuotaType, QuotaTypeEnum.sign.getCode())
                        );
                        BigDecimal signQuotaAmount = signQuota.getQuotaAmount() == null ? BigDecimal.ZERO : signQuota.getQuotaAmount();
                        BigDecimal signTempQuota = signQuota.getTempQuota() == null ? BigDecimal.ZERO : signQuota.getTempQuota();
                        signQuota.setOccupiedQuota(signOccupiedQuota);
                        signQuota.setSurplusQuota(signQuotaAmount.add(signTempQuota).subtract(signOccupiedQuota));
                        //剩余额度 = 签放额度+临时额度-占用额度
                        updateById(signQuota);
                        totalChannelQuotaInfoList.add(signQuota);
                    }
                }
            }
            if(totalChannelQuotaInfoList.size() > 0){
                //请求头
                Map<String, String> headers = new HashMap<>();
                //接口返回结果
                headers.put("clientId", caseConfig.getChannelClientId());
                headers.put("clientSecret", caseConfig.getChannelClientSecret());
                channelFeignService.updateChannelQuota(totalChannelQuotaInfoList, headers);
            }
        }
    }

}
